import { invoke } from "@tauri-apps/api/core";

class StreamingClient {
  async makeRequest(uri: string, method = "GET", body: string | null = null, headers = {}) {
    const localRequest = { uri, method, body, headers };
    const result = await invoke("handle_app_request", { localRequest });

    if ((result as any).type === "streaming") {
      return this.handleStreamingResponse(result as any);
    } else {
      return this.handleRegularResponse(result as any);
    }
  }

  async handleStreamingResponse(result: any) {
    const streamId = result.stream_id;
    const stream = new ReadableStream({
      start: (controller) => {
        this.readStreamChunks(streamId, controller);
      },
    });

    return {
      type: "streaming",
      statusCode: result.status_code,
      headers: result.headers,
      stream,
    };
  }

  async readStreamChunks(
    streamId: string,
    controller: ReadableStreamDefaultController<any>,
  ) {
    while (true) {
      const chunk = await invoke("get_stream_chunk", { streamId });

      if (!chunk) break;

      if ((chunk as any).data.length > 0) {
        controller.enqueue(new Uint8Array((chunk as any).data));
      }

      if ((chunk as any).is_final) {
        controller.close();
        break;
      }
    }
  }

  handleRegularResponse(result: any) {
    return {
      type: "regular",
      statusCode: result.status_code,
      headers: result.headers,
      body: result.body,
    };
  }
}

export default new StreamingClient();
